home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 10
/
AACD 10.iso
/
AACD
/
Games
/
MAME
/
src
/
machine
/
segacrpt.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-04-23
|
52KB
|
1,112 lines
/******************************************************************************
Sega encryption emulation by Nicola Salmoria
Several Sega Z80 games have program ROMs encrypted using a common algorithm
(but with a different key).
The hardware used to implement this encryption is either a custom CPU, or an
epoxy block which probably contains a standard Z80 + PALs.
You can think of the decryption algorithm as a black box which takes as
input D3, D5, D7, M1, A0, A4, A8 and A12, and returns the decrypted D3, D5
and D7. [Dn are the data lines, An the address lines, M1 is the Z80 pin which
tells whether the CPU is accessing data or opcodes]. D0, D1, D3, D4 and D6
are always unaffected.
We can summarize that using a XOR mask laid out like this:
0 1 2 3 4 5 6 7 8 9 a b c d e f
0 A A A A A A A A B B B B B B B B
1 A A A A A A A A B B B B B B B B
2 C C C C C C C C D D D D D D D D
3 C C C C C C C C D D D D D D D D
4 A A A A A A A A B B B B B B B B
5 A A A A A A A A B B B B B B B B
6 C C C C C C C C D D D D D D D D
7 C C C C C C C C D D D D D D D D
8 D D D D D D D D C C C C C C C C
9 D D D D D D D D C C C C C C C C
a B B B B B B B B A A A A A A A A
b B B B B B B B B A A A A A A A A
c D D D D D D D D C C C C C C C C
d D D D D D D D D C C C C C C C C
e B B B B B B B B A A A A A A A A
f B B B B B B B B A A A A A A A A
on the left edge you have the most significant nibble of the data, on the top
edge the least significant nibble. For example, if the input data is 0xc0, it
will be XORed with D. As you can see, the table is symmetrical, so the 8
possible combinations of D3, D5 and D7 only require 4 different XOR values.
Since only D3, D5 and D7 are affected, A, B, C and D can have only these
values: 0x00, 0x08, 0x20, 0x28, 0x80, 0x88, 0xa0, 0xa8.
Another important thing to note is that A XOR B XOR C XOR D must always be 0;
that is, it must cause a permutation. If that weren't the case, there would
be values impossible to obtain.
We need 32 of these tables, one for every possible combination of M1, A0, A4,
A8 and A12. However, all the games currently known are full of repetitions
and only use 6 different tables, the only exceptions being Pengo and Yamato
which have 7 (but one of them is { 0x00, 0x00, 0x00, 0x00 } ). This is most
likely a limitation of the hardware.
Some of the early games are even weaker: of the 6 different tables, they use
3 for opcodes and 3 for data, and always coupled in the same way.
In all games currently known, only bytes in the memory range 0x0000-0x7fff
(A15 = 0) are encrypted. My guess is that this was done to allow games to
copy code to RAM (in the memory range 0x8000-0xffff) and execute it from
there without the CPU trying to decrypt it and messing everything up.
However Zaxxon has RAM at 0x6000, and the CPU doesn't seem to interfere with
it; but it doesn't execute code from there, so it's possible that the CPU is
encrypting the data while writing it and decrypting it while reading (that
would seem kind of strange though). Video and sprite RAM and memory mapped
ports are all placed above 0x8000.
Given its strict limitations, this encryption is reasonably easy to break,
and very vulnerable to known plaintext attacks.
Ninja Princess:
there is a (bootleg?) board which has a standard Z80 + 2 bipolar PROMs
instead of the custom CPU. The encryption table is different from the
original Ninja Princess; it is actually the same as Flicky.
The first PROM is 32x8 (?) and contains the number (0..5) of the table to
use depending on M1, A0, A4, A8, A12:
00: 11 00 33 22 00 44 44 00 11 33 33 22 44 44 44 22
10: 11 55 55 33 44 22 55 22 11 33 55 33 44 44 11 22
The second PROM is 256x4 and contains the 6 different XOR tables:
A D B C C B D A
00: 09 09 0A 0A 0A 0A 09 09
08: 0E 08 0B 0D 0D 0B 08 0E
10: 0A 0C 0A 0C 0C 0A 0C 0A
18: 0B 0E 0E 0B 0B 0E 0E 0B
20: 0C 0C 0F 0F 0F 0F 0C 0C
28: 08 0D 0B 0E 0E 0B 0D 08
[the remaining bytes are all 0F]
bit 3 is not used.
bits 0-2 is the XOR code inverted (0 = 0xa8, 1 = 0xa0 ... 6 = 0x08 7 = 0x00)
Here is a diagram showing how it works:
data to XOR
decode value
A ---
D7 --------------- 0| |
D3 --------------- 1| |
D5 --------------- 2| P |D
A --- D | R |0 ---|>--- D3
M1 --- 0| P |0 --- 3| O |1 ---|>--- D5
A0 --- 1| R |1 --- 4| M |2 ---|>--- D7
A4 --- 2| O |2 --- 5| 2 |3 ---
A8 --- 3| M |3 --- 6| |
A12 --- 4| 1 |4 --- 7| |
--- ---
My Hero:
the bootleg does the decryption using a single 256x4 PROM, mapped in the
obvious way:
data to XOR
decode value
A ---
D3 --- 0| |
D5 --- 1| |D
D7 --- 2| P |0 --- D3
A0 --- 3| R |1 --- D5
A4 --- 4| O |2 --- D7
A8 --- 5| M |3 ---
A12 --- 6| |
M1 --- 7| |
---
List of encrypted games currently known:
CPU Part # Game Comments
315-5010 Pengo unencrypted version available
315-5013 Super Zaxxon used Zaxxon for known plaintext attack
???-???? Super Locomotive
???-???? M120 Razzmatazz same key as Ninja Princess
315-5018 Yamato
315-5028 Sindbad Mystery
315-5033 Regulus
315-5041 M140 Mister Viking
315-5048 SWAT used Bull Fight for k.p.a.
315-5051 Flicky &
Ninja Princess (bootleg)
???-???? Water Match not available yet
315-5061 Future Spy
315-5065 Bull Fight
315-5069 Star Force game by Tehkan; same key as Super Locomotive
315-5093 Pitfall II
315-5098 Ninja Princess unencrypted version available
315-5102 Sega Ninja unencrypted version available
315-5110 I'm Sorry used My Hero for k.p.a.
315-5114 ?? pcb 834-5492 not decoded yet
315-5115 TeddyBoy Blues
315-5135 Heavy Metal &
Wonder Boy (set 1 & 2; bootlegs?)
???-???? My Hero
The following games use a different encryption algorithm:
315-5162 4D Warriors used I'm Sorry for k.p.a.
315-5177 Wonder Boy (set 3) not decoded yet
315-5178 Wonder Boy (set 4) used Wonder Boy Deluxe for k.p.a.
???-???? Gardia not decoded yet
The following games use another different encryption algorithm, much more
secure than the previous two, which has not been broken yet. It might be
similar to the one used in System 16 games.
317-5014?DakkoChan Jansoh
317-0029 Block Gal NEC MC8123B 651 packaged like System16's 68000
317-0030 Perfect Billiards
317-0043 Wonder Boy Monster Land
317-0054 Shinobi (sound CPU) NEC MC8123B 651
317-0064 Ufo Senshi Yohko Chan
Some text found in the ROMs:
Super Locomotive SEGA FUKUMURA MIZUNAGA
Yamato SECULITY BY M,MIZUNAGA
Regulus SECULITY BY SYUICHI,KATAGI
Mister Viking SECURITY BY S.KATAGI CONTROL CHIP M140
SWAT SECURITY BY S.KATAGI
Flicky SECURITY BY S.KATAGI
Star Force STAR FORCE TEHKAN. SECURITY BY SEGA ENTERPRISESE
******************************************************************************/
#include "driver.h"
#ifdef MAME_DEBUG
static void lfkp(int mask)
{
int A;
unsigned char *RAM = memory_region(REGION_CPU1);
for (A = 0x0000;A < 0x8000-14;A++)
{
static char text[] = "INSERT COIN";
int i;
if ( (RAM[A+0] & mask) == (0x21 & mask) && /* LD HL,$xxxx */
(RAM[A+3] & mask) == (0x11 & mask) && /* LD DE,$xxxx */
(RAM[A+6] & mask) == (0x01 & mask)) /* LD BC,$xxxx */
{
if ( (RAM[A+ 9] & mask) == (0x36 & mask) && /* LD (HL),$xx */
(RAM[A+11] & mask) == (0xed & mask) &&
(RAM[A+12] & mask) == (0xb0 & mask)) /* LDIR */
logerror("%04x: hl de bc (hl),xx ldir\n",A);
if ( (RAM[A+ 9] & mask) == (0x77 & mask) && /* LD (HL),A */
(RAM[A+10] & mask) == (0xed & mask) &&
(RAM[A+11] & mask) == (0xb0 & mask)) /* LDIR */
logerror("%04x: hl de bc (hl),a ldir\n",A);
if ( (RAM[A+ 9] & mask) == (0xed & mask) &&
(RAM[A+10] & mask) == (0xb0 & mask)) /* LDIR */
logerror("%04x: hl de bc ldir\n",A);
}
/* the following can also be PUSH IX, PUSH IY - need better checking */
if ( (RAM[A+0] & mask) == (0xf5 & mask) && /* PUSH AF */
(RAM[A+1] & mask) == (0xc5 & mask) && /* PUSH BC */
(RAM[A+2] & mask) == (0xd5 & mask) && /* PUSH DE */
(RAM[A+3] & mask) == (0xe5 & mask)) /* PUSH HL */
logerror("%04x: push af bc de hl\n",A);
if ( (RAM[A+0] & mask) == (0xe1 & mask) && /* POP HL */
(RAM[A+1] & mask) == (0xd1 & mask) && /* POP DE */
(RAM[A+2] & mask) == (0xc1 & mask) && /* POP BC */
(RAM[A+3] & mask) == (0xf1 & mask)) /* POP AF */
logerror("%04x: pop hl de bc af\n",A);
for (i = 0;i < strlen(text);i++)
if ((RAM[A+i] & mask) != (text[i] & mask)) break;
if (i == strlen(text))
logerror("%04x: INSERT COIN\n",A);
}
}
static void look_for_known_plaintext(void)
{
lfkp(0x57);
}
static void read_table_from_disk(unsigned char *xortable)
{
FILE *f;
f = fopen("table","rb");
if (f) fread(xortable,1,128,f);
fclose(f);
}
#endif
static void sega_decode(const unsigned char xortable[32][4])
{
int A;
unsigned char *rom = memory_region(REGION_CPU1);
int diff = memory_region_length(REGION_CPU1) / 2;
memory_set_opcode_base(0,rom+diff);
for (A = 0x0000;A < 0x8000;A++)
{
int row,col;
unsigned char src;
src = rom[A];
/* pick the translation table from bits 0, 4, 8 and 12 of the address */
row = (A & 1) + (((A >> 4) & 1) << 1) + (((A >> 8) & 1) << 2) + (((A >> 12) & 1) << 3);
/* pick the offset in the table from bits 3 and 5 of the source data */
col = ((src >> 3) & 1) + (((src >> 5) & 1) << 1);
/* the bottom half of the translation table is the mirror image of the top */
if (src & 0x80) col = 3 - col;
/* decode the opcodes */
rom[A + diff] = src ^ xortable[2*row][col];
/* decode the data */
rom[A] = src ^ xortable[2*row+1][col];
if (xortable[2*row][col] == 0xff) /* table incomplete! (for development) */
rom[A + diff] = 0x00;
if (xortable[2*row+1][col] == 0xff) /* table incomplete! (for development) */
rom[A] = 0xee;
}
/* copy the opcodes from the not encrypted part of the ROMs */
for (A = 0x8000;A < diff;A++)
rom[A + diff] = rom[A];
}
void pengo_decode(void)
{
static const unsigned char xortable[32][4] =
{
/* opcode data address */
/* A B C D A B C D */
{ 0xa0,0x88,0x88,0xa0 }, { 0x28,0xa0,0x28,0xa0 }, /* ...0...0...0...0 */
{ 0x28,0xa0,0x28,0xa0 }, { 0xa0,0x88,0x88,0xa0 }, /* ...0...0...0...1 */
{ 0xa0,0x88,0x00,0x28 }, { 0xa0,0x88,0x00,0x28 }, /* ...0...0...1...0 */
{ 0x08,0x20,0xa8,0x80 }, { 0xa0,0x88,0x88,0xa0 }, /* ...0...0...1...1 */
{ 0x08,0x08,0xa8,0xa8 }, { 0x28,0xa0,0x28,0xa0 }, /* ...0...1...0...0 */
{ 0xa0,0x88,0x00,0x28 }, { 0x08,0x08,0xa8,0xa8 }, /* ...0...1...0...1 */
{ 0xa0,0x88,0x00,0x28 }, { 0xa0,0x88,0x00,0x28 }, /* ...0...1...1...0 */
{ 0xa0,0x88,0x00,0x28 }, { 0x00,0x00,0x00,0x00 }, /* ...0...1...1...1 */
{ 0x88,0x88,0x28,0x28 }, { 0xa0,0x88,0x00,0x28 }, /* ...1...0...0...0 */
{ 0x88,0x88,0x28,0x28 }, { 0x00,0x00,0x00,0x00 }, /* ...1...0...0...1 */
{ 0x08,0x20,0xa8,0x80 }, { 0x08,0x20,0xa8,0x80 }, /* ...1...0...1...0 */
{ 0xa0,0x88,0x88,0xa0 }, { 0xa0,0x88,0x00,0x28 }, /* ...1...0...1...1 */
{ 0x08,0x08,0xa8,0xa8 }, { 0x88,0x88,0x28,0x28 }, /* ...1...1...0...0 */
{ 0x00,0x00,0x00,0x00 }, { 0x88,0x88,0x28,0x28 }, /* ...1...1...0...1 */
{ 0x08,0x20,0xa8,0x80 }, { 0x08,0x20,0xa8,0x80 }, /* ...1...1...1...0 */
{ 0x08,0x08,0xa8,0xa8 }, { 0xa0,0x88,0x00,0x28 } /* ...1...1...1...1 */
};
sega_decode(xortable);
}
void szaxxon_decode(void)
{
static const unsigned char xortable[32][4] =
{
/* opcode data address */
/* A B C D A B C D */
{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x28,0x88,0x88 }, /* ...0...0...0...0 */
{ 0x08,0x20,0xa8,0x80 }, { 0x88,0x88,0x28,0x28 }, /* ...0...0...0...1 */
{ 0xa8,0x20,0x80,0x08 }, { 0x20,0xa8,0x20,0xa8 }, /* ...0...0...1...0 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x28,0x88,0x88 }, /* ...0...0...1...1 */
{ 0x08,0x20,0xa8,0x80 }, { 0x88,0x88,0x28,0x28 }, /* ...0...1...0...0 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x28,0x88,0x88 }, /* ...0...1...0...1 */
{ 0xa8,0x20,0x80,0x08 }, { 0x20,0xa8,0x20,0xa8 }, /* ...0...1...1...0 */
{ 0x08,0x20,0xa8,0x80 }, { 0x88,0x88,0x28,0x28 }, /* ...0...1...1...1 */
{ 0x08,0x20,0xa8,0x80 }, { 0x88,0x88,0x28,0x28 }, /* ...1...0...0...0 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x28,0x88,0x88 }, /* ...1...0...0...1 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x28,0x88,0x88 }, /* ...1...0...1...0 */
{ 0xa8,0x20,0x80,0x08 }, { 0x20,0xa8,0x20,0xa8 }, /* ...1...0...1...1 */
{ 0xa8,0x20,0x80,0x08 }, { 0x20,0xa8,0x20,0xa8 }, /* ...1...1...0...0 */
{ 0xa8,0x20,0x80,0x08 }, { 0x20,0xa8,0x20,0xa8 }, /* ...1...1...0...1 */
{ 0x08,0x20,0xa8,0x80 }, { 0x88,0x88,0x28,0x28 }, /* ...1...1...1...0 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x28,0x88,0x88 } /* ...1...1...1...1 */
};
sega_decode(xortable);
}
void suprloco_decode(void)
{
static const unsigned char xortable[32][4] =
{
/* opcode data address */
/* A B C D A B C D */
{ 0x20,0x08,0x80,0xa8 }, { 0xa8,0xa8,0xa8,0xa8 }, /* ...0...0...0...0 */
{ 0x20,0x08,0x80,0xa8 }, { 0xa8,0xa8,0xa8,0xa8 }, /* ...0...0...0...1 */
{ 0x20,0x08,0x80,0xa8 }, { 0xa8,0xa8,0xa8,0xa8 }, /* ...0...0...1...0 */
{ 0x88,0x00,0xa0,0x28 }, { 0xa0,0x88,0x88,0xa0 }, /* ...0...0...1...1 */
{ 0x88,0x00,0xa0,0x28 }, { 0xa0,0x88,0x88,0xa0 }, /* ...0...1...0...0 */
{ 0x20,0x08,0x80,0xa8 }, { 0xa8,0xa8,0xa8,0xa8 }, /* ...0...1...0...1 */
{ 0x88,0x00,0xa0,0x28 }, { 0xa0,0x88,0x88,0xa0 }, /* ...0...1...1...0 */
{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 }, /* ...0...1...1...1 */
{ 0x20,0x08,0x80,0xa8 }, { 0xa8,0xa8,0xa8,0xa8 }, /* ...1...0...0...0 */
{ 0x88,0x00,0xa0,0x28 }, { 0xa0,0x88,0x88,0xa0 }, /* ...1...0...0...1 */
{ 0x88,0x00,0xa0,0x28 }, { 0xa0,0x88,0x88,0xa0 }, /* ...1...0...1...0 */
{ 0x20,0x08,0x80,0xa8 }, { 0xa8,0xa8,0xa8,0xa8 }, /* ...1...0...1...1 */
{ 0x88,0x00,0xa0,0x28 }, { 0xa0,0x88,0x88,0xa0 }, /* ...1...1...0...0 */
{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 }, /* ...1...1...0...1 */
{ 0x20,0x08,0x80,0xa8 }, { 0xa8,0xa8,0xa8,0xa8 }, /* ...1...1...1...0 */
{ 0x88,0x00,0xa0,0x28 }, { 0xa0,0x88,0x88,0xa0 } /* ...1...1...1...1 */
};
sega_decode(xortable);
}
void yamato_decode(void)
{
static const unsigned char xortable[32][4] =
{
/* opcode data address */
/* A B C D A B C D */
{ 0x88,0xa0,0x28,0x00 }, { 0x88,0xa0,0xa0,0x88 }, /* ...0...0...0...0 */
{ 0x20,0xa8,0x08,0x80 }, { 0x88,0xa0,0xa0,0x88 }, /* ...0...0...0...1 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0xa0,0xa0,0x88 }, /* ...0...0...1...0 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x20,0xa8,0x08,0x80 }, /* ...0...0...1...1 */
{ 0x88,0xa0,0x28,0x00 }, { 0x88,0xa0,0x28,0x00 }, /* ...0...1...0...0 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0xa0,0xa0,0x88 }, /* ...0...1...0...1 */
{ 0x20,0xa8,0x08,0x80 }, { 0x20,0xa8,0x08,0x80 }, /* ...0...1...1...0 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0xa0,0xa0,0x88 }, /* ...0...1...1...1 */
{ 0x20,0xa8,0x08,0x80 }, { 0x88,0xa0,0x28,0x00 }, /* ...1...0...0...0 */
{ 0x20,0xa8,0x08,0x80 }, { 0x28,0x28,0x88,0x88 }, /* ...1...0...0...1 */
{ 0xa0,0x28,0xa0,0x28 }, { 0x20,0xa8,0x08,0x80 }, /* ...1...0...1...0 */
{ 0x28,0x28,0x88,0x88 }, { 0x20,0xa8,0x08,0x80 }, /* ...1...0...1...1 */
{ 0x20,0xa8,0x08,0x80 }, { 0x88,0xa0,0x28,0x00 }, /* ...1...1...0...0 */
{ 0x88,0xa0,0x28,0x00 }, { 0x88,0xa0,0x28,0x00 }, /* ...1...1...0...1 */
{ 0xa0,0x28,0xa0,0x28 }, { 0x88,0x00,0xa0,0x28 }, /* ...1...1...1...0 */
{ 0x20,0xa8,0x08,0x80 }, { 0x00,0x00,0x00,0x00 } /* ...1...1...1...1 */
};
sega_decode(xortable);
}
void sindbadm_decode(void)
{
static const unsigned char xortable[32][4] =
{
/* opcode data address */
/* A B C D A B C D */
{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 }, /* ...0...0...0...0 */
{ 0xa8,0xa8,0xa8,0xa8 }, { 0x00,0x28,0xa0,0x88 }, /* ...0...0...0...1 */
{ 0xa8,0xa8,0xa8,0xa8 }, { 0x00,0x28,0xa0,0x88 }, /* ...0...0...1...0 */
{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 }, /* ...0...0...1...1 */
{ 0xa8,0x80,0x80,0xa8 }, { 0xa0,0x28,0x88,0x00 }, /* ...0...1...0...0 */
{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 }, /* ...0...1...0...1 */
{ 0xa8,0xa8,0xa8,0xa8 }, { 0x00,0x28,0xa0,0x88 }, /* ...0...1...1...0 */
{ 0xa8,0xa8,0xa8,0xa8 }, { 0x00,0x28,0xa0,0x88 }, /* ...0...1...1...1 */
{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 }, /* ...1...0...0...0 */
{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 }, /* ...1...0...0...1 */
{ 0xa8,0xa8,0xa8,0xa8 }, { 0x00,0x28,0xa0,0x88 }, /* ...1...0...1...0 */
{ 0xa8,0xa8,0xa8,0xa8 }, { 0x00,0x28,0xa0,0x88 }, /* ...1...0...1...1 */
{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 }, /* ...1...1...0...0 */
{ 0xa8,0x80,0x80,0xa8 }, { 0xa0,0x28,0x88,0x00 }, /* ...1...1...0...1 */
{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 }, /* ...1...1...1...0 */
{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 } /* ...1...1...1...1 */
};
sega_decode(xortable);
}
void regulus_decode(void)
{
static const unsigned char xortable[32][4] =
{
/* opcode data address */
/* A B C D A B C D */
{ 0x28,0x00,0x88,0xa0 }, { 0x88,0x88,0x28,0x28 }, /* ...0...0...0...0 */
{ 0x28,0x00,0x88,0xa0 }, { 0x28,0xa0,0x28,0xa0 }, /* ...0...0...0...1 */
{ 0x88,0x88,0x28,0x28 }, { 0x88,0x00,0xa0,0x28 }, /* ...0...0...1...0 */
{ 0x88,0x00,0xa0,0x28 }, { 0x28,0xa0,0x28,0xa0 }, /* ...0...0...1...1 */
{ 0x28,0x00,0x88,0xa0 }, { 0x88,0x88,0x28,0x28 }, /* ...0...1...0...0 */
{ 0x88,0x88,0x28,0x28 }, { 0x88,0x88,0x28,0x28 }, /* ...0...1...0...1 */
{ 0x88,0x00,0xa0,0x28 }, { 0x88,0x00,0xa0,0x28 }, /* ...0...1...1...0 */
{ 0xa0,0x88,0x88,0xa0 }, { 0xa0,0x88,0x88,0xa0 }, /* ...0...1...1...1 */
{ 0x80,0xa8,0x20,0x08 }, { 0x28,0x00,0x88,0xa0 }, /* ...1...0...0...0 */
{ 0x28,0xa0,0x28,0xa0 }, { 0x28,0x00,0x88,0xa0 }, /* ...1...0...0...1 */
{ 0x80,0xa8,0x20,0x08 }, { 0x80,0xa8,0x20,0x08 }, /* ...1...0...1...0 */
{ 0x28,0xa0,0x28,0xa0 }, { 0x80,0xa8,0x20,0x08 }, /* ...1...0...1...1 */
{ 0xa0,0x88,0x88,0xa0 }, { 0x28,0x00,0x88,0xa0 }, /* ...1...1...0...0 */
{ 0x80,0xa8,0x20,0x08 }, { 0xa0,0x88,0x88,0xa0 }, /* ...1...1...0...1 */
{ 0xa0,0x88,0x88,0xa0 }, { 0x80,0xa8,0x20,0x08 }, /* ...1...1...1...0 */
{ 0xa0,0x88,0x88,0xa0 }, { 0xa0,0x88,0x88,0xa0 } /* ...1...1...1...1 */
};
sega_decode(xortable);
}
void mrviking_decode(void)
{
static const unsigned char xortable[32][4] =
{
/* opcode data address */
/* A B C D A B C D */
{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x88,0x28,0x28 }, /* ...0...0...0...0 */
{ 0x88,0x00,0xa0,0x28 }, { 0x88,0x88,0x28,0x28 }, /* ...0...0...0...1 */
{ 0x28,0x00,0x88,0xa0 }, { 0x28,0xa0,0x28,0xa0 }, /* ...0...0...1...0 */
{ 0x88,0x00,0xa0,0x28 }, { 0x88,0x00,0xa0,0x28 }, /* ...0...0...1...1 */
{ 0x28,0x00,0x88,0xa0 }, { 0x88,0x88,0x28,0x28 }, /* ...0...1...0...0 */
{ 0x88,0x88,0x28,0x28 }, { 0x28,0xa0,0x28,0xa0 }, /* ...0...1...0...1 */
{ 0xa0,0x88,0x88,0xa0 }, { 0x28,0x00,0x88,0xa0 }, /* ...0...1...1...0 */
{ 0xa0,0x88,0x88,0xa0 }, { 0xa0,0x88,0x88,0xa0 }, /* ...0...1...1...1 */
{ 0x88,0x88,0x28,0x28 }, { 0x88,0x88,0x28,0x28 }, /* ...1...0...0...0 */
{ 0x88,0x00,0xa0,0x28 }, { 0x88,0x88,0x28,0x28 }, /* ...1...0...0...1 */
{ 0xa0,0x88,0x00,0x28 }, { 0x28,0x00,0x88,0xa0 }, /* ...1...0...1...0 */
{ 0xa0,0x88,0x00,0x28 }, { 0x88,0x00,0xa0,0x28 }, /* ...1...0...1...1 */
{ 0x28,0x00,0x88,0xa0 }, { 0xa0,0x88,0x00,0x28 }, /* ...1...1...0...0 */
{ 0xa0,0x88,0x00,0x28 }, { 0xa0,0x88,0x00,0x28 }, /* ...1...1...0...1 */
{ 0xa0,0x88,0x88,0xa0 }, { 0x28,0x00,0x88,0xa0 }, /* ...1...1...1...0 */
{ 0xa0,0x88,0x00,0x28 }, { 0xa0,0x88,0x88,0xa0 } /* ...1...1...1...1 */
};
sega_decode(xortable);
}
void swat_decode(void)
{
static const unsigned char xortable[32][4] =
{
/* opcode data address */
/* A B C D A B C D */
{ 0x88,0x00,0xa0,0x28 }, { 0xa0,0xa0,0xa0,0xa0 }, /* ...0...0...0...0 */
{ 0x88,0x00,0xa0,0x28 }, { 0x88,0xa0,0xa0,0x88 }, /* ...0...0...0...1 */
{ 0xa0,0x88,0x00,0x28 }, { 0x88,0x00,0xa0,0x28 }, /* ...0...0...1...0 */
{ 0xa0,0xa0,0xa0,0xa0 }, { 0x88,0x00,0xa0,0x28 }, /* ...0...0...1...1 */
{ 0x28,0x28,0x88,0x88 }, { 0xa0,0xa0,0xa0,0xa0 }, /* ...0...1...0...0 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x28,0x88,0x88 }, /* ...0...1...0...1 */
{ 0xa0,0x88,0x00,0x28 }, { 0xa0,0xa0,0xa0,0xa0 }, /* ...0...1...1...0 */
{ 0x28,0x28,0x88,0x88 }, { 0xa0,0xa0,0xa0,0xa0 }, /* ...0...1...1...1 */
{ 0xa0,0x88,0x00,0x28 }, { 0xa0,0x88,0x00,0x28 }, /* ...1...0...0...0 */
{ 0xa0,0x28,0xa0,0x28 }, { 0x88,0xa0,0xa0,0x88 }, /* ...1...0...0...1 */
{ 0xa0,0x28,0xa0,0x28 }, { 0xa0,0x28,0xa0,0x28 }, /* ...1...0...1...0 */
{ 0xa0,0x28,0xa0,0x28 }, { 0xa0,0x28,0xa0,0x28 }, /* ...1...0...1...1 */
{ 0xa0,0x88,0x00,0x28 }, { 0xa0,0x88,0x00,0x28 }, /* ...1...1...0...0 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x28,0x88,0x88 }, /* ...1...1...0...1 */
{ 0xa0,0xa0,0xa0,0xa0 }, { 0xa0,0x88,0x00,0x28 }, /* ...1...1...1...0 */
{ 0x28,0x28,0x88,0x88 }, { 0xa0,0xa0,0xa0,0xa0 } /* ...1...1...1...1 */
};
sega_decode(xortable);
}
void flicky_decode(void)
{
static const unsigned char xortable[32][4] =
{
/* opcode data address */
/* A B C D A B C D */
{ 0x08,0x80,0x20,0xa8 }, { 0xa0,0x88,0x88,0xa0 }, /* ...0...0...0...0 */
{ 0x80,0x08,0x80,0x08 }, { 0x88,0x88,0x28,0x28 }, /* ...0...0...0...1 */
{ 0xa0,0x88,0x88,0xa0 }, { 0x28,0x00,0x00,0x28 }, /* ...0...0...1...0 */
{ 0x28,0x00,0x00,0x28 }, { 0xa0,0x88,0x88,0xa0 }, /* ...0...0...1...1 */
{ 0x08,0x80,0x20,0xa8 }, { 0x80,0x08,0x80,0x08 }, /* ...0...1...0...0 */
{ 0x80,0x08,0x80,0x08 }, { 0x88,0x88,0x28,0x28 }, /* ...0...1...0...1 */
{ 0x28,0x00,0x00,0x28 }, { 0x28,0x00,0x00,0x28 }, /* ...0...1...1...0 */
{ 0x28,0x00,0x00,0x28 }, { 0x88,0x88,0x28,0x28 }, /* ...0...1...1...1 */
{ 0x08,0x80,0x20,0xa8 }, { 0xa8,0x80,0x08,0x20 }, /* ...1...0...0...0 */
{ 0xa8,0x80,0x08,0x20 }, { 0x80,0x08,0x80,0x08 }, /* ...1...0...0...1 */
{ 0x28,0x00,0x00,0x28 }, { 0x88,0x88,0x28,0x28 }, /* ...1...0...1...0 */
{ 0xa8,0x80,0x08,0x20 }, { 0x88,0x88,0x28,0x28 }, /* ...1...0...1...1 */
{ 0x08,0x80,0x20,0xa8 }, { 0x80,0x08,0x80,0x08 }, /* ...1...1...0...0 */
{ 0xa8,0x80,0x08,0x20 }, { 0x80,0x08,0x80,0x08 }, /* ...1...1...0...1 */
{ 0x28,0x00,0x00,0x28 }, { 0x28,0x00,0x00,0x28 }, /* ...1...1...1...0 */
{ 0x08,0x80,0x20,0xa8 }, { 0x88,0x88,0x28,0x28 } /* ...1...1...1...1 */
};
sega_decode(xortable);
}
void futspy_decode(void)
{
static const unsigned char xortable[32][4] =
{
/* opcode data address */
/* A B C D A B C D */
{ 0x28,0x00,0x00,0x28 }, { 0x28,0x00,0x00,0x28 }, /* ...0...0...0...0 */
{ 0x80,0x08,0x80,0x08 }, { 0x08,0x80,0x20,0xa8 }, /* ...0...0...0...1 */
{ 0x80,0x08,0x80,0x08 }, { 0x08,0x80,0x20,0xa8 }, /* ...0...0...1...0 */
{ 0xa0,0x88,0x00,0x28 }, { 0x20,0x20,0x80,0x80 }, /* ...0...0...1...1 */
{ 0x28,0x00,0x00,0x28 }, { 0x88,0x88,0x88,0x88 }, /* ...0...1...0...0 */
{ 0x80,0x08,0x80,0x08 }, { 0x08,0x80,0x20,0xa8 }, /* ...0...1...0...1 */
{ 0x80,0x08,0x80,0x08 }, { 0x20,0x20,0x80,0x80 }, /* ...0...1...1...0 */
{ 0x20,0x20,0x80,0x80 }, { 0x08,0x80,0x20,0xa8 }, /* ...0...1...1...1 */
{ 0x88,0x88,0x88,0x88 }, { 0x28,0x00,0x00,0x28 }, /* ...1...0...0...0 */
{ 0x80,0x08,0x80,0x08 }, { 0xa0,0x88,0x00,0x28 }, /* ...1...0...0...1 */
{ 0x20,0x20,0x80,0x80 }, { 0x08,0x80,0x20,0xa8 }, /* ...1...0...1...0 */
{ 0x80,0x08,0x80,0x08 }, { 0x20,0x20,0x80,0x80 }, /* ...1...0...1...1 */
{ 0x88,0x88,0x88,0x88 }, { 0x88,0x88,0x88,0x88 }, /* ...1...1...0...0 */
{ 0x80,0x08,0x80,0x08 }, { 0x08,0x80,0x20,0xa8 }, /* ...1...1...0...1 */
{ 0x80,0x08,0x80,0x08 }, { 0x28,0x00,0x00,0x28 }, /* ...1...1...1...0 */
{ 0x20,0x20,0x80,0x80 }, { 0xa0,0x88,0x00,0x28 } /* ...1...1...1...1 */
};
sega_decode(xortable);
}
void bullfgtj_decode(void)
{
static const unsigned char xortable[32][4] =
{
/* opcode data address */
/* A B C D A B C D */
{ 0xa0,0xa0,0x00,0x00 }, { 0x80,0xa8,0x20,0x08 }, /* ...0...0...0...0 */
{ 0x20,0x20,0x20,0x20 }, { 0x20,0x20,0x20,0x20 }, /* ...0...0...0...1 */
{ 0xa0,0xa0,0x00,0x00 }, { 0x08,0x20,0x20,0x08 }, /* ...0...0...1...0 */
{ 0x88,0x00,0x88,0x00 }, { 0x88,0x00,0x88,0x00 }, /* ...0...0...1...1 */
{ 0xa0,0xa0,0x00,0x00 }, { 0x20,0x20,0x20,0x20 }, /* ...0...1...0...0 */
{ 0x28,0xa0,0x00,0x88 }, { 0x20,0x20,0x20,0x20 }, /* ...0...1...0...1 */
{ 0xa0,0xa0,0x00,0x00 }, { 0x08,0x20,0x20,0x08 }, /* ...0...1...1...0 */
{ 0x88,0x00,0x88,0x00 }, { 0x88,0x00,0x88,0x00 }, /* ...0...1...1...1 */
{ 0x28,0xa0,0x00,0x88 }, { 0xa0,0xa0,0x00,0x00 }, /* ...1...0...0...0 */
{ 0x88,0x00,0x88,0x00 }, { 0x80,0xa8,0x20,0x08 }, /* ...1...0...0...1 */
{ 0x28,0xa0,0x00,0x88 }, { 0x08,0x20,0x20,0x08 }, /* ...1...0...1...0 */
{ 0x28,0xa0,0x00,0x88 }, { 0x80,0xa8,0x20,0x08 }, /* ...1...0...1...1 */
{ 0x20,0x20,0x20,0x20 }, { 0x20,0x20,0x20,0x20 }, /* ...1...1...0...0 */
{ 0x88,0x00,0x88,0x00 }, { 0x20,0x20,0x20,0x20 }, /* ...1...1...0...1 */
{ 0x08,0x20,0x20,0x08 }, { 0x80,0xa8,0x20,0x08 }, /* ...1...1...1...0 */
{ 0x08,0x20,0x20,0x08 }, { 0x88,0x00,0x88,0x00 } /* ...1...1...1...1 */
};
sega_decode(xortable);
}
void pitfall2_decode(void)
{
static const unsigned char xortable[32][4] =
{
/* opcode data address */
/* A B C D A B C D */
{ 0xa0,0x88,0x88,0xa0 }, { 0xa0,0x88,0x88,0xa0 }, /* ...0...0...0...0 */
{ 0x08,0x80,0x08,0x80 }, { 0x28,0xa0,0x00,0x88 }, /* ...0...0...0...1 */
{ 0xa0,0x88,0x88,0xa0 }, { 0xa0,0x88,0x88,0xa0 }, /* ...0...0...1...0 */
{ 0xa0,0xa0,0x00,0x00 }, { 0xa0,0xa0,0x00,0x00 }, /* ...0...0...1...1 */
{ 0xa0,0x88,0x88,0xa0 }, { 0x20,0x08,0x80,0xa8 }, /* ...0...1...0...0 */
{ 0x28,0xa0,0x00,0x88 }, { 0x20,0x08,0x80,0xa8 }, /* ...0...1...0...1 */
{ 0xa0,0xa0,0x00,0x00 }, { 0xa0,0xa0,0x00,0x00 }, /* ...0...1...1...0 */
{ 0x28,0xa0,0x00,0x88 }, { 0xa0,0xa0,0x00,0x00 }, /* ...0...1...1...1 */
{ 0x20,0x08,0x80,0xa8 }, { 0x80,0x80,0x80,0x80 }, /* ...1...0...0...0 */
{ 0x80,0x80,0x80,0x80 }, { 0x80,0x80,0x80,0x80 }, /* ...1...0...0...1 */
{ 0xa0,0xa0,0x00,0x00 }, { 0xa0,0x88,0x88,0xa0 }, /* ...1...0...1...0 */
{ 0x80,0x80,0x80,0x80 }, { 0x28,0xa0,0x00,0x88 }, /* ...1...0...1...1 */
{ 0x20,0x08,0x80,0xa8 }, { 0x80,0x80,0x80,0x80 }, /* ...1...1...0...0 */
{ 0x80,0x80,0x80,0x80 }, { 0x20,0x08,0x80,0xa8 }, /* ...1...1...0...1 */
{ 0xa0,0xa0,0x00,0x00 }, { 0xa0,0x88,0x88,0xa0 }, /* ...1...1...1...0 */
{ 0x80,0x80,0x80,0x80 }, { 0x28,0xa0,0x00,0x88 } /* ...1...1...1...1 */
};
sega_decode(xortable);
}
void nprinces_decode(void)
{
static const unsigned char xortable[32][4] =
{
/* opcode data address */
/* A B C D A B C D */
{ 0x08,0x80,0x20,0xa8 }, { 0xa0,0x28,0xa0,0x28 }, /* ...0...0...0...0 */
{ 0xa8,0xa8,0x08,0x08 }, { 0x88,0xa0,0xa0,0x88 }, /* ...0...0...0...1 */
{ 0x88,0x88,0x28,0x28 }, { 0x28,0x00,0x88,0xa0 }, /* ...0...0...1...0 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x00,0x88,0xa0 }, /* ...0...0...1...1 */
{ 0x88,0xa0,0xa0,0x88 }, { 0xa0,0x28,0xa0,0x28 }, /* ...0...1...0...0 */
{ 0xa8,0xa8,0x08,0x08 }, { 0xa8,0xa8,0x08,0x08 }, /* ...0...1...0...1 */
{ 0x88,0x88,0x28,0x28 }, { 0x88,0xa0,0xa0,0x88 }, /* ...0...1...1...0 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0xa0,0xa0,0x88 }, /* ...0...1...1...1 */
{ 0xa0,0x28,0xa0,0x28 }, { 0xa0,0x28,0xa0,0x28 }, /* ...1...0...0...0 */
{ 0x08,0x80,0x20,0xa8 }, { 0x28,0x00,0x88,0xa0 }, /* ...1...0...0...1 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0x88,0x28,0x28 }, /* ...1...0...1...0 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x00,0x88,0xa0 }, /* ...1...0...1...1 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0xa0,0xa0,0x88 }, /* ...1...1...0...0 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0xa0,0xa0,0x88 }, /* ...1...1...0...1 */
{ 0x88,0x88,0x28,0x28 }, { 0x88,0x88,0x28,0x28 }, /* ...1...1...1...0 */
{ 0x08,0x80,0x20,0xa8 }, { 0x28,0x00,0x88,0xa0 } /* ...1...1...1...1 */
};
sega_decode(xortable);
}
void seganinj_decode(void)
{
static const unsigned char xortable[32][4] =
{
/* opcode data address */
/* A B C D A B C D */
{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0x00,0xa0,0x28 }, /* ...0...0...0...0 */
{ 0x28,0xa0,0x28,0xa0 }, { 0xa0,0xa0,0xa0,0xa0 }, /* ...0...0...0...1 */
{ 0xa8,0xa8,0x08,0x08 }, { 0xa8,0xa8,0x08,0x08 }, /* ...0...0...1...0 */
{ 0x28,0xa0,0x28,0xa0 }, { 0xa0,0xa0,0xa0,0xa0 }, /* ...0...0...1...1 */
{ 0x28,0x00,0x88,0xa0 }, { 0x28,0x00,0x88,0xa0 }, /* ...0...1...0...0 */
{ 0x28,0xa0,0x28,0xa0 }, { 0x88,0x00,0xa0,0x28 }, /* ...0...1...0...1 */
{ 0x28,0x00,0x88,0xa0 }, { 0x28,0x00,0x88,0xa0 }, /* ...0...1...1...0 */
{ 0x28,0xa0,0x28,0xa0 }, { 0xa8,0xa8,0x08,0x08 }, /* ...0...1...1...1 */
{ 0x88,0x00,0xa0,0x28 }, { 0x88,0xa0,0xa0,0x88 }, /* ...1...0...0...0 */
{ 0xa0,0xa0,0xa0,0xa0 }, { 0x28,0xa0,0x28,0xa0 }, /* ...1...0...0...1 */
{ 0xa8,0xa8,0x08,0x08 }, { 0x88,0xa0,0xa0,0x88 }, /* ...1...0...1...0 */
{ 0xa8,0xa8,0x08,0x08 }, { 0x28,0xa0,0x28,0xa0 }, /* ...1...0...1...1 */
{ 0x28,0x00,0x88,0xa0 }, { 0x88,0xa0,0xa0,0x88 }, /* ...1...1...0...0 */
{ 0x28,0x00,0x88,0xa0 }, { 0x28,0x00,0x88,0xa0 }, /* ...1...1...0...1 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0xa0,0xa0,0x88 }, /* ...1...1...1...0 */
{ 0xa8,0xa8,0x08,0x08 }, { 0x28,0x00,0x88,0xa0 } /* ...1...1...1...1 */
};
sega_decode(xortable);
}
void imsorry_decode(void)
{
static const unsigned char xortable[32][4] =
{
/* opcode data address */
/* A B C D A B C D */
{ 0x88,0x00,0xa0,0x28 }, { 0x00,0x28,0xa0,0x88 }, /* ...0...0...0...0 */
{ 0x00,0x28,0xa0,0x88 }, { 0x88,0x00,0xa0,0x28 }, /* ...0...0...0...1 */
{ 0x88,0x00,0x88,0x00 }, { 0x00,0x28,0xa0,0x88 }, /* ...0...0...1...0 */
{ 0x00,0x28,0xa0,0x88 }, { 0x88,0x00,0x88,0x00 }, /* ...0...0...1...1 */
{ 0x00,0x28,0xa0,0x88 }, { 0x08,0x08,0xa8,0xa8 }, /* ...0...1...0...0 */
{ 0x00,0x28,0xa0,0x88 }, { 0x20,0x20,0x80,0x80 }, /* ...0...1...0...1 */
{ 0x20,0x20,0x80,0x80 }, { 0x00,0x28,0xa0,0x88 }, /* ...0...1...1...0 */
{ 0x20,0x20,0x80,0x80 }, { 0x88,0x00,0x88,0x00 }, /* ...0...1...1...1 */
{ 0x88,0x00,0xa0,0x28 }, { 0x08,0x08,0xa8,0xa8 }, /* ...1...0...0...0 */
{ 0x08,0x08,0xa8,0xa8 }, { 0x88,0x00,0xa0,0x28 }, /* ...1...0...0...1 */
{ 0x08,0x20,0x20,0x08 }, { 0x08,0x20,0x20,0x08 }, /* ...1...0...1...0 */
{ 0x88,0x00,0xa0,0x28 }, { 0x08,0x20,0x20,0x08 }, /* ...1...0...1...1 */
{ 0x08,0x20,0x20,0x08 }, { 0x08,0x08,0xa8,0xa8 }, /* ...1...1...0...0 */
{ 0x08,0x20,0x20,0x08 }, { 0x20,0x20,0x80,0x80 }, /* ...1...1...0...1 */
{ 0x20,0x20,0x80,0x80 }, { 0x08,0x20,0x20,0x08 }, /* ...1...1...1...0 */
{ 0x20,0x20,0x80,0x80 }, { 0x08,0x20,0x20,0x08 } /* ...1...1...1...1 */
};
sega_decode(xortable);
}
void teddybb_decode(void)
{
static const unsigned char xortable[32][4] =
{
/* opcode data address */
/* A B C D A B C D */
{ 0x20,0x20,0x20,0x20 }, { 0x80,0x08,0x80,0x08 }, /* ...0...0...0...0 */
{ 0x20,0x20,0x20,0x20 }, { 0xa0,0xa0,0x00,0x00 }, /* ...0...0...0...1 */
{ 0x28,0x00,0x88,0xa0 }, { 0xa0,0x88,0x88,0xa0 }, /* ...0...0...1...0 */
{ 0xa0,0xa0,0x00,0x00 }, { 0xa0,0x88,0x88,0xa0 }, /* ...0...0...1...1 */
{ 0x20,0x20,0x20,0x20 }, { 0x28,0x00,0x88,0xa0 }, /* ...0...1...0...0 */
{ 0xa0,0xa0,0x00,0x00 }, { 0xa0,0xa0,0x00,0x00 }, /* ...0...1...0...1 */
{ 0xa0,0x88,0x88,0xa0 }, { 0x28,0x00,0x88,0xa0 }, /* ...0...1...1...0 */
{ 0xa0,0xa0,0x00,0x00 }, { 0x28,0x00,0x88,0xa0 }, /* ...0...1...1...1 */
{ 0x80,0x08,0x80,0x08 }, { 0x80,0x08,0x80,0x08 }, /* ...1...0...0...0 */
{ 0xa0,0x28,0x88,0x00 }, { 0xa0,0xa0,0x00,0x00 }, /* ...1...0...0...1 */
{ 0xa0,0x28,0x88,0x00 }, { 0xa0,0x88,0x88,0xa0 }, /* ...1...0...1...0 */
{ 0xa0,0x88,0x88,0xa0 }, { 0xa0,0x88,0x88,0xa0 }, /* ...1...0...1...1 */
{ 0x80,0x08,0x80,0x08 }, { 0x20,0x20,0x20,0x20 }, /* ...1...1...0...0 */
{ 0xa0,0xa0,0x00,0x00 }, { 0xa0,0x28,0x88,0x00 }, /* ...1...1...0...1 */
{ 0x80,0x08,0x80,0x08 }, { 0xa0,0x88,0x88,0xa0 }, /* ...1...1...1...0 */
{ 0xa0,0xa0,0x00,0x00 }, { 0xa0,0x28,0x88,0x00 } /* ...1...1...1...1 */
};
sega_decode(xortable);
}
void hvymetal_decode(void)
{
static const unsigned char xortable[32][4] =
{
/* opcode data address */
/* A B C D A B C D */
{ 0x88,0xa0,0xa0,0x88 }, { 0xa0,0x88,0x88,0xa0 }, /* ...0...0...0...0 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0x88,0x28,0x28 }, /* ...0...0...0...1 */
{ 0xa0,0x88,0x88,0xa0 }, { 0x88,0xa0,0xa0,0x88 }, /* ...0...0...1...0 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x88,0x88,0x28,0x28 }, /* ...0...0...1...1 */
{ 0xa0,0x88,0x88,0xa0 }, { 0x88,0x88,0x28,0x28 }, /* ...0...1...0...0 */
{ 0x88,0x88,0x28,0x28 }, { 0x88,0x88,0x28,0x28 }, /* ...0...1...0...1 */
{ 0xa0,0x88,0x88,0xa0 }, { 0x88,0x88,0x28,0x28 }, /* ...0...1...1...0 */
{ 0x88,0x88,0x28,0x28 }, { 0x28,0x00,0x88,0xa0 }, /* ...0...1...1...1 */
{ 0xa0,0x28,0x88,0x00 }, { 0x88,0xa0,0xa0,0x88 }, /* ...1...0...0...0 */
{ 0xa0,0x28,0x88,0x00 }, { 0x88,0xa0,0xa0,0x88 }, /* ...1...0...0...1 */
{ 0xa0,0x28,0x88,0x00 }, { 0x88,0xa0,0xa0,0x88 }, /* ...1...0...1...0 */
{ 0x88,0xa0,0xa0,0x88 }, { 0x28,0x00,0x88,0xa0 }, /* ...1...0...1...1 */
{ 0x28,0xa0,0x28,0xa0 }, { 0xa0,0x28,0x88,0x00 }, /* ...1...1...0...0 */
{ 0xa0,0x28,0x88,0x00 }, { 0x28,0xa0,0x28,0xa0 }, /* ...1...1...0...1 */
{ 0x28,0xa0,0x28,0xa0 }, { 0xa0,0x28,0x88,0x00 }, /* ...1...1...1...0 */
{ 0x28,0x00,0x88,0xa0 }, { 0x28,0xa0,0x28,0xa0 } /* ...1...1...1...1 */
};
sega_decode(xortable);
}
void myheroj_decode(void)
{
static const unsigned char xortable[32][4] =
{
/* opcode data address */
/* A B C D A B C D */
{ 0x20,0x08,0x80,0xa8 }, { 0x80,0xa8,0xa8,0x80 }, /* ...0...0...0...0 */
{ 0x20,0x08,0x80,0xa8 }, { 0x80,0xa8,0xa8,0x80 }, /* ...0...0...0...1 */
{ 0xa8,0xa8,0xa8,0xa8 }, { 0xa8,0xa8,0xa8,0xa8 }, /* ...0...0...1...0 */
{ 0x08,0x80,0x20,0xa8 }, { 0x80,0xa8,0xa8,0x80 }, /* ...0...0...1...1 */
{ 0x20,0x08,0x80,0xa8 }, { 0x28,0xa0,0x28,0xa0 }, /* ...0...1...0...0 */
{ 0x20,0x08,0x80,0xa8 }, { 0x08,0x80,0x20,0xa8 }, /* ...0...1...0...1 */
{ 0x28,0xa0,0x28,0xa0 }, { 0xa8,0xa8,0xa8,0xa8 }, /* ...0...1...1...0 */
{ 0x08,0x80,0x20,0xa8 }, { 0xa8,0xa8,0xa8,0xa8 }, /* ...0...1...1...1 */
{ 0x28,0xa0,0x28,0xa0 }, { 0x20,0x08,0x80,0xa8 }, /* ...1...0...0...0 */
{ 0x80,0xa8,0xa8,0x80 }, { 0x20,0x08,0x80,0xa8 }, /* ...1...0...0...1 */
{ 0x80,0xa8,0xa8,0x80 }, { 0x80,0xa8,0xa8,0x80 }, /* ...1...0...1...0 */
{ 0xa8,0xa8,0xa8,0xa8 }, { 0x80,0xa8,0xa8,0x80 }, /* ...1...0...1...1 */
{ 0x88,0x88,0x28,0x28 }, { 0x88,0x88,0x28,0x28 }, /* ...1...1...0...0 */
{ 0x88,0x88,0x28,0x28 }, { 0x08,0x80,0x20,0xa8 }, /* ...1...1...0...1 */
{ 0x88,0x88,0x28,0x28 }, { 0xa8,0xa8,0xa8,0xa8 }, /* ...1...1...1...0 */
{ 0x88,0x88,0x28,0x28 }, { 0xa8,0xa8,0xa8,0xa8 } /* ...1...1...1...1 */
};
sega_decode(xortable);
}
/******************************************************************************
4D Warriors
This encryption is quite different from the standard one. It is still
a XOR scheme, but the value to use for the XOR is chosen differently, and
the affected bits are D0, D2, D4 and D6 instead of D3, D5 and D7.
The translation table depends on A0, A3, A6, A9, A12 and A14; however A0, A3
and A6 only select some fixed additional XOR, so there are only 8 really
different tables.
There are no separate tables for data and opcodes: the opcodes are just XORed
with an additional 0x40. To make it a little more complicated, however, data
picks its XOR value not from the line given by the address but from the one
below. For example if you are decoding a byte at address .1.0..1..0..1..0,
you pick the XOR value as if you were at address .1.0..1..0..1..1 (note that
I'm not talking about the rows of the xortable below, but of the "logical"
ones which are generated by them with the additional fixed XORs selected by
A0, A3 and A6).
******************************************************************************/
void fdwarrio_decode(void)
{
static const unsigned char xortable[8+1][8] =
{
/* note how the first lines are highly repetitive, while the */
/* last ones get more and more unique. */
{ 0x00,0x00,0x14,0x14,0x14,0x14,0x00,0x00 }, /* .0.0..0..x..x..x */
{ 0x00,0x11,0x00,0x11,0x11,0x00,0x11,0x00 }, /* .0.0..1..x..x..x */
{ 0x00,0x05,0x05,0x00,0x00,0x05,0x05,0x00 }, /* .0.1..0..x..x..x */
{ 0x00,0x00,0x44,0x44,0x14,0x14,0x50,0x50 }, /* .0.1..1..x..x..x */
{ 0x00,0x00,0x14,0x14,0x50,0x50,0x44,0x44 }, /* .1.0..0..x..x..x */
{ 0x00,0x05,0x05,0x00,0x50,0x55,0x55,0x50 }, /* .1.0..1..x..x..x */
{ 0x00,0x11,0x05,0x14,0x14,0x05,0x11,0x00 }, /* .1.1..0..x..x..x */
{ 0x00,0x41,0x05,0x44,0x14,0x55,0x11,0x50 }, /* .1.1..1..x..x..x */
{ 0x00,0x11,0x05,0x14,0x50,0x41,0x55,0x44 } /* extra line for data decode */
};
int A;
unsigned char *rom = memory_region(REGION_CPU1);
int diff = memory_region_length(REGION_CPU1) / 2;
memory_set_opcode_base(0,rom+diff);
for (A = 0x0000;A < 0x8000;A++)
{
int row,col;
unsigned char src;
src = rom[A];
/* pick the translation table from bits 0, 3, 6, 9, 12 and 14 of the address */
row = (A & 1) + (((A >> 3) & 1) << 1) + (((A >> 6) & 1) << 2)
+ (((A >> 9) & 1) << 3) + (((A >> 12) & 1) << 4) + (((A >> 14) & 1) << 5);
/* pick the offset in the table from bits 0, 2, 4 and 6 of the source data */
col = ((src >> 0) & 1) + (((src >> 2) & 1) << 1) + (((src >> 4) & 1) << 2);
/* the bottom half of the translation table is the mirror image of the top */
if (src & 0x40) col = 7 - col;
/* decode the opcodes */
rom[A + diff] = src ^ xortable[row >> 3][col] ^ 0x40;
if (row & 1) rom[A + diff] ^= 0x10;
if (row & 2) rom[A + diff] ^= 0x04;
if (row & 4) rom[A + diff] ^= 0x01;
/* decode the data */
row++; /* the data XOR table is shifted by one position!!!! */
rom[A] = src ^ xortable[row >> 3][col];
if (row & 1) rom[A] ^= 0x10;
if (row & 2) rom[A] ^= 0x04;
if (row & 4) rom[A] ^= 0x01;
}
/* copy the opcodes from the not encrypted part of the ROMs */
for (A = 0x8000;A < diff;A++)
rom[A + diff] = rom[A];
}
/******************************************************************************
Wonder Boy
This is different again. It is similar to 4D Warriors - it affects the same
data bits and is selected by the same address lines, but I haven't been able
to find any regularities in the XOR table, so I'm using a huge 1024 bytes
array.
******************************************************************************/
void wboy3_decode(void)
{
/* not decoded yet! */
}
void wboy4_decode(void)
{
static const unsigned char opcode_xortable[8*8][8] =
{
{ 0x00,0x00,0x44,0x44,0x00,0x00,0x44,0x44 }, /* .0.0 ..0. .0.. 0..0 */
{ 0x45,0x54,0x45,0x54,0x54,0x45,0x54,0x45 }, /* .0.0 ..0. .0.. 0..1 */
{ 0x11,0x11,0x11,0x11,0x41,0x41,0x41,0x41 }, /* .0.0 ..0. .0.. 1..0 */
{ 0x01,0x10,0x01,0x10,0x10,0x01,0x10,0x01 }, /* .0.0 ..0. .0.. 1..1 */
{ 0x44,0x44,0x44,0x44,0x14,0x14,0x14,0x14 }, /* .0.0 ..0. .1.. 0..0 */
{ 0x10,0x01,0x10,0x01,0x01,0x10,0x01,0x10 }, /* .0.0 ..0. .1.. 0..1 */
{ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55 }, /* .0.0 ..0. .1.. 1..0 */
{ 0x05,0x05,0x11,0x11,0x11,0x11,0x05,0x05 }, /* .0.0 ..0. .1.. 1..1 */
{ 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41 }, /* .0.0 ..1. .0.. 0..0 */
{ 0x14,0x14,0x00,0x00,0x00,0x00,0x14,0x14 }, /* .0.0 ..1. .0.. 0..1 */
{ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04 }, /* .0.0 ..1. .0.. 1..0 */
{ 0x40,0x40,0x54,0x54,0x54,0x54,0x40,0x40 }, /* .0.0 ..1. .0.. 1..1 */
{ 0x15,0x15,0x51,0x51,0x01,0x01,0x45,0x45 }, /* .0.0 ..1. .1.. 0..0 */
{ 0x51,0x10,0x51,0x10,0x51,0x10,0x51,0x10 }, /* .0.0 ..1. .1.. 0..1 */
{ 0x01,0x01,0x45,0x45,0x15,0x15,0x51,0x51 }, /* .0.0 ..1. .1.. 1..0 */
{ 0x44,0x05,0x44,0x05,0x44,0x05,0x44,0x05 }, /* .0.0 ..1. .1.. 1..1 */
{ 0x10,0x10,0x54,0x54,0x04,0x04,0x40,0x40 }, /* .0.1 ..0. .0.. 0..0 */
{ 0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41 }, /* .0.1 ..0. .0.. 0..1 */
{ 0x45,0x40,0x40,0x45,0x45,0x40,0x40,0x45 }, /* .0.1 ..0. .0.. 1..0 */
{ 0x11,0x11,0x55,0x55,0x11,0x11,0x55,0x55 }, /* .0.1 ..0. .0.. 1..1 */
{ 0x54,0x51,0x51,0x54,0x54,0x51,0x51,0x54 }, /* .0.1 ..0. .1.. 0..0 */
{ 0x04,0x04,0x40,0x40,0x04,0x04,0x40,0x40 }, /* .0.1 ..0. .1.. 0..1 */
{ 0x40,0x45,0x45,0x40,0x40,0x45,0x45,0x40 }, /* .0.1 ..0. .1.. 1..0 */
{ 0x15,0x15,0x15,0x15,0x45,0x45,0x45,0x45 }, /* .0.1 ..0. .1.. 1..1 */
{ 0x05,0x14,0x05,0x14,0x14,0x05,0x14,0x05 }, /* .0.1 ..1. .0.. 0..0 */
{ 0x41,0x41,0x41,0x41,0x11,0x11,0x11,0x11 }, /* .0.1 ..1. .0.. 0..1 */
{ 0x14,0x05,0x14,0x05,0x05,0x14,0x05,0x14 }, /* .0.1 ..1. .0.. 1..0 */
{ 0x50,0x50,0x50,0x50,0x00,0x00,0x00,0x00 }, /* .0.1 ..1. .0.. 1..1 */
{ 0x00,0x11,0x00,0x11,0x11,0x00,0x11,0x00 }, /* .0.1 ..1. .1.. 0..0 */
{ 0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45 }, /* .0.1 ..1. .1.. 0..1 */
{ 0x11,0x11,0x05,0x05,0x05,0x05,0x11,0x11 }, /* .0.1 ..1. .1.. 1..0 */
{ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 }, /* .0.1 ..1. .1.. 1..1 */
{ 0x00,0x11,0x05,0x14,0x14,0x05,0x11,0x00 }, /* .1.0 ..0. .0.. 0..0 */
{ 0x45,0x04,0x40,0x01,0x45,0x04,0x40,0x01 }, /* .1.0 ..0. .0.. 0..1 */
{ 0x11,0x14,0x14,0x11,0x41,0x44,0x44,0x41 }, /* .1.0 ..0. .0.. 1..0 */
{ 0x01,0x40,0x04,0x45,0x01,0x40,0x04,0x45 }, /* .1.0 ..0. .0.. 1..1 */
{ 0x44,0x41,0x41,0x44,0x14,0x11,0x11,0x14 }, /* .1.0 ..0. .1.. 0..0 */
{ 0x10,0x51,0x15,0x54,0x10,0x51,0x15,0x54 }, /* .1.0 ..0. .1.. 0..1 */
{ 0x55,0x55,0x41,0x41,0x05,0x05,0x11,0x11 }, /* .1.0 ..0. .1.. 1..0 */
{ 0x05,0x14,0x00,0x11,0x55,0x44,0x50,0x41 }, /* .1.0 ..0. .1.. 1..1 */
{ 0x41,0x41,0x55,0x55,0x11,0x11,0x05,0x05 }, /* .1.0 ..1. .0.. 0..0 */
{ 0x14,0x05,0x11,0x00,0x44,0x55,0x41,0x50 }, /* .1.0 ..1. .0.. 0..1 */
{ 0x04,0x04,0x10,0x10,0x54,0x54,0x40,0x40 }, /* .1.0 ..1. .0.. 1..0 */
{ 0x40,0x51,0x45,0x54,0x10,0x01,0x15,0x04 }, /* .1.0 ..1. .0.. 1..1 */
{ 0x15,0x10,0x51,0x54,0x04,0x01,0x40,0x45 }, /* .1.0 ..1. .1.. 0..0 */
{ 0x51,0x10,0x54,0x15,0x45,0x04,0x40,0x01 }, /* .1.0 ..1. .1.. 0..1 */
{ 0x01,0x04,0x45,0x40,0x10,0x15,0x54,0x51 }, /* .1.0 ..1. .1.. 1..0 */
{ 0x44,0x05,0x41,0x00,0x50,0x11,0x55,0x14 }, /* .1.0 ..1. .1.. 1..1 */
/* the following are all FF because there is no code to decode */
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, /* .1.1 ..0. .0.. 0..0 */
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, /* .1.1 ..0. .0.. 0..1 */
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, /* .1.1 ..0. .0.. 1..0 */
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, /* .1.1 ..0. .0.. 1..1 */
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, /* .1.1 ..0. .1.. 0..0 */
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, /* .1.1 ..0. .1.. 0..1 */
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, /* .1.1 ..0. .1.. 1..0 */
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, /* .1.1 ..0. .1.. 1..1 */
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, /* .1.1 ..1. .0.. 0..0 */
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, /* .1.1 ..1. .0.. 0..1 */
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, /* .1.1 ..1. .0.. 1..0 */
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, /* .1.1 ..1. .0.. 1..1 */
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, /* .1.1 ..1. .1.. 0..0 */
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, /* .1.1 ..1. .1.. 0..1 */
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, /* .1.1 ..1. .1.. 1..0 */
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }, /* .1.1 ..1. .1.. 1..1 */
};
static const unsigned char data_xortable[8*8][8] =
{
{ 0x55,0x14,0x55,0x14,0x55,0x14,0x55,0x14 }, /* .0.0 ..0. .0.. 0..0 */
{ 0x05,0x05,0x41,0x41,0x11,0x11,0x55,0x55 }, /* .0.0 ..0. .0.. 0..1 */
{ 0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00 }, /* .0.0 ..0. .0.. 1..0 */
{ 0x14,0x14,0x50,0x50,0x00,0x00,0x44,0x44 }, /* .0.0 ..0. .0.. 1..1 */
{ 0x50,0x11,0x50,0x11,0x50,0x11,0x50,0x11 }, /* .0.0 ..0. .1.. 0..0 */
{ 0x00,0x00,0x44,0x44,0x14,0x14,0x50,0x50 }, /* .0.0 ..0. .1.. 0..1 */
{ 0x15,0x15,0x51,0x51,0x15,0x15,0x51,0x51 }, /* .0.0 ..0. .1.. 1..0 */
{ 0x51,0x54,0x54,0x51,0x51,0x54,0x54,0x51 }, /* .0.0 ..0. .1.. 1..1 */
{ 0x01,0x01,0x45,0x45,0x01,0x01,0x45,0x45 }, /* .0.0 ..1. .0.. 0..0 */
{ 0x44,0x41,0x41,0x44,0x44,0x41,0x41,0x44 }, /* .0.0 ..1. .0.. 0..1 */
{ 0x10,0x10,0x54,0x54,0x10,0x10,0x54,0x54 }, /* .0.0 ..1. .0.. 1..0 */
{ 0x55,0x44,0x55,0x44,0x44,0x55,0x44,0x55 }, /* .0.0 ..1. .0.. 1..1 */
{ 0x05,0x05,0x05,0x05,0x55,0x55,0x55,0x55 }, /* .0.0 ..1. .1.. 0..0 */
{ 0x11,0x00,0x11,0x00,0x00,0x11,0x00,0x11 }, /* .0.0 ..1. .1.. 0..1 */
{ 0x54,0x54,0x54,0x54,0x04,0x04,0x04,0x04 }, /* .0.0 ..1. .1.. 1..0 */
{ 0x04,0x15,0x04,0x15,0x15,0x04,0x15,0x04 }, /* .0.0 ..1. .1.. 1..1 */
{ 0x40,0x40,0x40,0x40,0x10,0x10,0x10,0x10 }, /* .0.1 ..0. .0.. 0..0 */
{ 0x15,0x15,0x01,0x01,0x01,0x01,0x15,0x15 }, /* .0.1 ..0. .0.. 0..1 */
{ 0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51 }, /* .0.1 ..0. .0.. 1..0 */
{ 0x01,0x01,0x15,0x15,0x15,0x15,0x01,0x01 }, /* .0.1 ..0. .0.. 1..1 */
{ 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14 }, /* .0.1 ..0. .1.. 0..0 */
{ 0x50,0x50,0x44,0x44,0x44,0x44,0x50,0x50 }, /* .0.1 ..0. .1.. 0..1 */
{ 0x00,0x00,0x14,0x14,0x50,0x50,0x44,0x44 }, /* .0.1 ..0. .1.. 1..0 */
{ 0x45,0x04,0x45,0x04,0x45,0x04,0x45,0x04 }, /* .0.1 ..0. .1.. 1..1 */
{ 0x11,0x11,0x55,0x55,0x05,0x05,0x41,0x41 }, /* .0.1 ..1. .0.. 0..0 */
{ 0x54,0x15,0x54,0x15,0x54,0x15,0x54,0x15 }, /* .0.1 ..1. .0.. 0..1 */
{ 0x04,0x04,0x40,0x40,0x10,0x10,0x54,0x54 }, /* .0.1 ..1. .0.. 1..0 */
{ 0x10,0x51,0x10,0x51,0x10,0x51,0x10,0x51 }, /* .0.1 ..1. .0.. 1..1 */
{ 0x55,0x50,0x50,0x55,0x55,0x50,0x50,0x55 }, /* .0.1 ..1. .1.. 0..0 */
{ 0x05,0x05,0x41,0x41,0x05,0x05,0x41,0x41 }, /* .0.1 ..1. .1.. 0..1 */
{ 0x41,0x44,0x44,0x41,0x41,0x44,0x44,0x41 }, /* .0.1 ..1. .1.. 1..0 */
{ 0x14,0x14,0x50,0x50,0x14,0x14,0x50,0x50 }, /* .0.1 ..1. .1.. 1..1 */
{ 0x55,0x14,0x50,0x11,0x41,0x00,0x44,0x05 }, /* .1.0 ..0. .0.. 0..0 */
{ 0x05,0x00,0x41,0x44,0x14,0x11,0x50,0x55 }, /* .1.0 ..0. .0.. 0..1 */
{ 0x41,0x00,0x44,0x05,0x55,0x14,0x50,0x11 }, /* .1.0 ..0. .0.. 1..0 */
{ 0x14,0x11,0x50,0x55,0x05,0x00,0x41,0x44 }, /* .1.0 ..0. .0.. 1..1 */
{ 0x50,0x11,0x55,0x14,0x44,0x05,0x41,0x00 }, /* .1.0 ..0. .1.. 0..0 */
{ 0x00,0x05,0x44,0x41,0x11,0x14,0x55,0x50 }, /* .1.0 ..0. .1.. 0..1 */
{ 0x15,0x04,0x10,0x01,0x01,0x10,0x04,0x15 }, /* .1.0 ..0. .1.. 1..0 */
{ 0x51,0x54,0x45,0x40,0x40,0x45,0x54,0x51 }, /* .1.0 ..0. .1.. 1..1 */
{ 0x01,0x10,0x04,0x15,0x15,0x04,0x10,0x01 }, /* .1.0 ..1. .0.. 0..0 */
{ 0x44,0x41,0x50,0x55,0x55,0x50,0x41,0x44 }, /* .1.0 ..1. .0.. 0..1 */
{ 0x10,0x01,0x15,0x04,0x04,0x15,0x01,0x10 }, /* .1.0 ..1. .0.. 1..0 */
{ 0x55,0x14,0x50,0x11,0x55,0x14,0x50,0x11 }, /* .1.0 ..1. .0.. 1..1 */
{ 0x05,0x00,0x00,0x05,0x55,0x50,0x50,0x55 }, /* .1.0 ..1. .1.. 0..0 */
{ 0x11,0x50,0x14,0x55,0x11,0x50,0x14,0x55 }, /* .1.0 ..1. .1.. 0..1 */
{ 0x54,0x51,0x51,0x54,0x04,0x01,0x01,0x04 }, /* .1.0 ..1. .1.. 1..0 */
{ 0x04,0x45,0x01,0x40,0x04,0x45,0x01,0x40 }, /* .1.0 ..1. .1.. 1..1 */
{ 0x40,0x45,0x45,0x40,0x10,0x15,0x15,0x10 }, /* .1.1 ..0. .0.. 0..0 */
{ 0x15,0x04,0x10,0x01,0x45,0x54,0x40,0x51 }, /* .1.1 ..0. .0.. 0..1 */
{ 0x51,0x51,0x45,0x45,0x01,0x01,0x15,0x15 }, /* .1.1 ..0. .0.. 1..0 */
{ 0x01,0x10,0x04,0x15,0x51,0x40,0x54,0x45 }, /* .1.1 ..0. .0.. 1..1 */
{ 0x14,0x14,0x00,0x00,0x44,0x44,0x50,0x50 }, /* .1.1 ..0. .1.. 0..0 */
{ 0x50,0x41,0x55,0x44,0x00,0x11,0x05,0x14 }, /* .1.1 ..0. .1.. 0..1 */
{ 0x00,0x41,0x00,0x41,0x11,0x50,0x11,0x50 }, /* .1.1 ..0. .1.. 1..0 */
{ 0x45,0x04,0x40,0x01,0x51,0x10,0x54,0x15 }, /* .1.1 ..0. .1.. 1..1 */
{ 0x11,0x14,0x55,0x50,0x00,0x05,0x44,0x41 }, /* .1.1 ..1. .0.. 0..0 */
{ 0x54,0x15,0x51,0x10,0x40,0x01,0x45,0x04 }, /* .1.1 ..1. .0.. 0..1 */
{ 0x04,0x01,0x40,0x45,0x15,0x10,0x51,0x54 }, /* .1.1 ..1. .0.. 1..0 */
{ 0x10,0x51,0x15,0x54,0x04,0x45,0x01,0x40 }, /* .1.1 ..1. .0.. 1..1 */
{ 0x55,0x50,0x41,0x44,0x44,0x41,0x50,0x55 }, /* .1.1 ..1. .1.. 0..0 */
{ 0x05,0x14,0x00,0x11,0x11,0x00,0x14,0x05 }, /* .1.1 ..1. .1.. 0..1 */
{ 0x41,0x44,0x55,0x50,0x50,0x55,0x44,0x41 }, /* .1.1 ..1. .1.. 1..0 */
{ 0x14,0x05,0x11,0x00,0x00,0x11,0x05,0x14 }, /* .1.1 ..1. .1.. 1..1 */
};
int A;
unsigned char *rom = memory_region(REGION_CPU1);
int diff = memory_region_length(REGION_CPU1) / 2;
memory_set_opcode_base(0,rom+diff);
for (A = 0x0000;A < 0x8000;A++)
{
int row,col;
unsigned char src;
src = rom[A];
/* pick the translation table from bits 0, 3, 6, 9, 12 and 14 of the address */
row = (A & 1) + (((A >> 3) & 1) << 1) + (((A >> 6) & 1) << 2)
+ (((A >> 9) & 1) << 3) + (((A >> 12) & 1) << 4) + (((A >> 14) & 1) << 5);
/* pick the offset in the table from bits 0, 2, 4 and 6 of the source data */
col = ((src >> 0) & 1) + (((src >> 2) & 1) << 1) + (((src >> 4) & 1) << 2);
/* the bottom half of the translation table is the mirror image of the top */
if (src & 0x40) col = 7 - col;
/* decode the opcodes */
rom[A + diff] = src ^ opcode_xortable[row][col] ^ 0x00;
/* decode the data */
rom[A] = src ^ data_xortable[row][col];
}
/* copy the opcodes from the not encrypted part of the ROMs */
for (A = 0x8000;A < diff;A++)
rom[A + diff] = rom[A];
}
void gardia_decode(void)
{
/* not decoded yet! */
}